package com.googlecode.cswish.security.auth;


import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.googlecode.cswish.security.type.Expression;
import com.googlecode.cswish.security.type.RuleSetOr;
import com.googlecode.cswish.security.validator.Equals;


/**
 * @author Jerry.Feng Date: Nov 8, 2007 1:54:10 PM
 * @version $id: $
 */
public class Parser {
	private static final Logger logger = Logger.getLogger(Parser.class);
	
	private ClassLoader loader;
	
	public Parser() {
		loader = Parser.class.getClassLoader();
	}
	
	private static final Parser instance = new Parser();
	
	public static Parser getInstance() {
		return instance;
	}

	/**
	 * p1=v1&p2=v2|p3=v3|func1:params
	 * 
	 * @param value
	 * @return
	 */
	public RuleSetOr parse(String value) {
		// 1. split by '|'
		String[] level1 = StringUtils.split(value, '|');
		
		RuleSetOr condition = new RuleSetOr();
		// 2. split by '&'
		for (int i = 0; i < level1.length; i++) {
			String[] level2 = StringUtils.split(value, '&');
			
			// 3. create the expression
			Expression[] expressions = new Expression[level2.length];
			for (int j = 0; j < level2.length; j++) {
				Expression express = createExpression(level2[j]);
				expressions[j] = express;
			}
			
			// TODO:
			//condition.addRule(expressions);
		}
		
		return condition;
	}
	
	/**
	 * type 1:
	 * p3=v3
	 * type 2:
	 * func1:params
	 * 
	 * @param value
	 * @return
	 */
	private Expression createExpression(String value) {
		// type 1
		int index = value.indexOf('=');
		if (index > 0) {
			String paramName = value.substring(0, index);
			String paramValue = value.substring(index + 1);
			
			return new Equals(paramName, paramValue);
		}
		
		// typ 2
		index = value.indexOf(':');
		if (index > 0) {
			String funcName = value.substring(0, index);
			String paramValue = value.substring(index + 1);
			String[] paramValues = StringUtils.split(paramValue, ',');
			return getExpression(funcName, paramValues);
		}
		
		return null;
	}
	
	public Expression getExpression(String funcName, String[] paramValues) {
		// TODO: get class name according to function name
		String className = funcName;
        try {
        	Class clzz = loader.loadClass(className);
        	// TODO: pass parameter to constructor
            Object obj = clzz.newInstance();
			if (obj instanceof Expression) {
				return (Expression)obj;
			}
        } catch (Exception ex) {
            logger.debug(ex);
        }

		return null;
	}
}
